﻿using JT808Protocol.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Common
{
    /// <summary>
    /// 日志记录器
    /// </summary>
    public class LogCollector
    {
        private readonly object _logQueueObj = new object();
        private readonly Queue<JT808Package> _logQueue = new Queue<JT808Package>();
        private bool _bRunning;
        private Task _taskDealWithData;
        private CancellationTokenSource _cts;
        private CancellationToken _ct;

        private string _sourceDataPath;

        /// <summary>
        /// 日志记录器
        /// </summary>
        /// <param name="analyseBase"></param>
        public LogCollector(string sourceDataPath)
        {
            if (string.IsNullOrEmpty(sourceDataPath))
            {
                throw new Exception("原始数据日志目录为空");
            }
            _sourceDataPath = sourceDataPath;
        }

        /// <summary>
        /// 添加日志
        /// </summary>
        /// <param name="logData"></param>
        public void AddInLogQueue(JT808Package logData)
        {
            lock (_logQueueObj)
            {
                _logQueue.Enqueue(logData);
            }
        }

        private void SaveSourceData(List<JT808Package> lstLogData)
        {
            foreach (var logData in lstLogData)
            {
                var path = _sourceDataPath + @"\" + DateTime.Now.ToString("yyyy-MM-dd") + @"\" + logData.Header.SimNumber + ".log";
                DataWriter.WriteGpsTextData(path, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"), logData.WriteSpan(isEsc: true));
            }
        }

        /// <summary>
        /// 启动
        /// </summary>
        public void OnStart()
        {
            if (_taskDealWithData != null || _bRunning)
            {
                return;
            }

            _bRunning = true;
            _cts = new CancellationTokenSource();
            _ct = _cts.Token;
            _taskDealWithData = Task.Factory.StartNew(DealWithQueueData);
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void OnStop()
        {
            if (_taskDealWithData == null)
            {
                return;
            }
            _bRunning = false;

            //等待其它线程退出
            Thread.Sleep(300);

            try
            {
                //中止线程
                _cts.Cancel();
            }
            finally
            {
                _taskDealWithData = null;
            }
        }

        private void DealWithQueueData()
        {
            while (_bRunning)
            {
                try
                {
                    if (_ct.IsCancellationRequested)
                    {
                        _ct.ThrowIfCancellationRequested();
                    }

                    var dtStart = DateTime.Now;

                    //复制队列数据,以免长期占用锁
                    List<JT808Package> queueCopy;

                    lock (_logQueueObj)
                    {
                        //复制队列
                        queueCopy = new List<JT808Package>(_logQueue);
                        _logQueue.Clear();
                    }

                    if (queueCopy.Count > 0)
                    {
                        SaveSourceData(queueCopy);
                    }

                    //清除已存数据
                    queueCopy.Clear();

                    var ts = DateTime.Now - dtStart;
                    if (ts.TotalMilliseconds > 200)
                    {
                        continue;
                    }

                    var nMilliseconds = 200 - Convert.ToInt32(ts.TotalMilliseconds);
                    Thread.Sleep(nMilliseconds);
                }
                catch (Exception ex)
                {
                }
            }
        }
    }
}